/*
  首先，我们的代码被加载到页面中的时候，是需要立即执行的。所以输出的bundle.js实质上要是一个立即执行函数。我们主要注意以下几点：
  1. 我们写模块的时候，用的是 import/export.经转换后,变成了require/exports
  2. 我们要让require/exports能正常运行，那么我们得定义这两个东西，并加到bundle.js里
  3. 在依赖图谱里，代码都成了字符串。要执行，可以使用eval
  4. 定义一个require函数，require函数的本质是执行一个模块的代码，然后将相应变量挂载到exports对象上
  5. 获取整个项目的依赖图谱，从入口开始，调用require方法。完整代码如下：
*/

const exportGraph = require('./exportGraph.js');
const exportBundle = require('./exportBundle.js');

const exportCode = (entry) => {
  const graph = JSON.stringify(exportGraph(entry));

  exportBundle(`
      (function(graph) {
        //require函数的本质是执行一个模块的代码，然后将相应变量挂载到exports对象上
        function require(module) {
            //localRequire的本质是拿到依赖包的exports变量
            function localRequire(relativePath) {
                return require(graph[module].dependencies[relativePath]);
            }
            var exports = {};
            (function(require, exports, code) {
                eval(code);
            })(localRequire, exports, graph[module].code);
            return exports;
            //函数返回指向局部变量，形成闭包，exports变量在函数执行后不会被摧毁
        }
        require('${entry}')
    })(${graph})`);
};

module.exports = exportCode;
